package com.supermap.ar.unity.slam;

import android.util.Log;

import androidx.annotation.Keep;

import com.google.are.sceneform.Camera;
import com.google.are.sceneform.math.Quaternion;
import com.google.are.sceneform.math.Vector3;
import com.supermap.ar.unity.UnityToolkit;
import com.supermap.ar.unity.utils.CoordinateUtils;

/**
 * SLAM java对象
 * <p>用于unity和android之间的姿态数据互传</p>
 * @author tanyx
 * @version 1.0
 * <br/>SampleCode:<br/>
 * <code>
 *     SlamObject.getInstance().setCameraPoseListener(new CameraPoseListener()){
 *         //...
 *     };
 * </code>
 **/
public class SlamObject {
    private static SlamObject mInstance = null;
    private boolean isDebug = true;
    private CameraPoseData cameraPoseDataCache;
    public final String UNITY_OBJECT_NAME = "SuperMap_IMB_System";
    private static PoseDataConfig mPoseDataConfig;

    /**
     * 相机姿态监听器
     */
    private CameraPoseListener mCameraPoseListener;

    /**
     * 获取实例
     * @return
     */
    public static SlamObject getInstance() {
        if (mInstance == null){
            synchronized (SlamObject.class){
                if (mInstance == null){
                    mInstance = new SlamObject();
                }
            }
        }
        return mInstance;
    }

    private SlamObject(){

    }

    /**
     * 设置相机姿态更新监听
     * @param mCameraPoseListener
     */
    public void setCameraPoseListener(CameraPoseListener mCameraPoseListener) {
        this.mCameraPoseListener = mCameraPoseListener;
    }

    public void updateUnityCamera(CameraPoseData cameraPoseData){
        this.cameraPoseDataCache = cameraPoseData;
    }

    /**
     * 获取姿态导出设置
     * @return 设置 {@link PoseDataConfig}
     */
    public PoseDataConfig getConfig() {
        return mPoseDataConfig;
    }

    /**
     * 设置姿态导出设置
     * @param mPoseDataConfig 设置 {@link PoseDataConfig}
     */
    public void setConfig(PoseDataConfig mPoseDataConfig) {
        this.mPoseDataConfig = mPoseDataConfig;
        //更新Unity端参数
        boolean setPoseDataSetting = UnityToolkit.callUnity(UNITY_OBJECT_NAME, "SetPoseDataSetting", this.mPoseDataConfig.toString());
        if (!setPoseDataSetting){
            throw new RuntimeException("failed");
        }
    }

    /**=================Unity 中调用的方法- start =================*/
    @Keep
    String getConfigStr() {
        return mPoseDataConfig.toString();
    }

    @Keep
    static boolean setConfigStrFromUnity(String configStr){
        if ("ONLY_EXPORT".equals(configStr)){
            mPoseDataConfig = PoseDataConfig.ONLY_EXPORT;
        }
        else if ("ONLY_IMPORT".equals(configStr)){
            mPoseDataConfig = PoseDataConfig.ONLY_IMPORT;
        }
        else if ("ALL".equals(configStr)){
            mPoseDataConfig = PoseDataConfig.ALL;
        }
        else if ("NONE".equals(configStr)){
            mPoseDataConfig = PoseDataConfig.NONE;
        }else {
            return false;
        }
        return true;
    }


    /**
     * 获取当前相机姿态缓存字符串
     * @return
     */
    @Keep
    String getCurrentCameraPose(){
        if (mCameraPoseListener != null){
            mCameraPoseListener.updateCameraPose(cameraPoseDataCache);
        }
        return cameraPoseDataCache.toJson();
    }

    /**
     * 更新相机姿态
     */
    @Keep
    boolean updateCameraPose(String jsonStr){
        if (mCameraPoseListener == null)return false;
        mCameraPoseListener.updateCameraPose(CameraPoseData.getObject(jsonStr));
        return true;
    }

    @Keep
    void onStartSlam(){
        mCameraPoseListener.onStartSlam();
        if (isDebug){
            Log.i(SlamObject.class.getSimpleName(), "OnStartSlam");
        }
    }

    @Keep
    void onDestroySlam(){
        mCameraPoseListener.onDestroySlam();
        if (isDebug){
            Log.i(SlamObject.class.getSimpleName(), "OnDestroySlam");
        }
    }

    /**=================Unity 中调用的方法-  end  =================*/
}
